home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-04-12 | 59.0 KB | 2,134 lines |
- This is an official patch to nn release 6.4
- -------------------------------------------
-
- PATCH #15
-
- Priority: LOW
-
-
- This patch adds a CONSOLIDATED MENU mode to nn. When a consolidated
- menu is used each different subject (or "thread") is only shown once
- on the menu by combining all articles with identical subjects into a
- single line. Since only one menu line is used even for articles with
- follow-ups, the number of articles presented on each menu page can be
- increased significantly.
-
- To turn on the consolidated menu feature, just add the following line
- to your init file:
- set consolidated-menu
-
- When consolidated menus are used, nn operates with two kinds of
- subjects: closed and open.
-
- An open subject is a subject which is shown in the traditional way
- with one menu line for each article with the given subject. In other
- words, when consolidated menus are not used, all subjects are open (by
- default).
-
- A closed subject is a multi-article subject which is presented by a
- single menu line. This line will be the normal menu line for the
- first (oldest) article with the subject, but with the subject field
- annotated with a bracketed number showing the number of articles with
- that subject, e.g.
-
- a Kim F. Storm 12 [4] Future plans for nn 6.4
- b.Kim F. Storm 43 [3] More plans for nn 6.4
-
- In this example, there are four unread articles with subject `a' of
- which the first is posted by me and has 12 lines. The rest of the
- articles are hidden, and will only be shown on request.
-
- The `.' marker on subject `b' shows that all three articles within
- that subject have been read or seen (to simplify presentation on the
- menu, the `seen' attribute is treated as the `read' attribute within a
- closed subject; they are still handled separately when necessary, e.g.
- when updating .newsrc and by the junk-articles command).
-
- To select (or deselect) ALL the articles within a closed subject,
- simply select the article shown on the menu; this will automatically
- select (or deselect) the hidden *unread* articles (by default; see
- auto-select-closed for changing this behaviour). When all the unread
- articles within a closed subject are selected, the menu line will be
- high-lighted.
-
- If you want to view the individual articles in a subject (maybe to
- select individual articles depending on the sender's name), you can
- open the subject with the commands:
- (x open subject x on menu
- (( open current subject
-
- When you have completed viewing the opened subject, you can close it
- again using the commands:
- )x close subject x on menu (x is any article with the subject)
- )) close current subject
-
- In the basic layout of the menu line for a closed subject as shown
- above, ALL articles in the closed subject are supposed to be either:
-
- unread menu line is not high-lighted
- selected menu line is fully high-lighted (if all UNREAD are selected)
- read/seen there is a '.' (read attribute) following the article id
-
- If this is not the case, i.e. there are a mixture of unread, selected,
- and read articles, the bracketed number will have one of the following
- formats:
- [U:T] there are U unread articles of T total (U<T)
- [S/T] there are S selected articles of T total (S<U=T)
- [S/U:T] there are S selected of U unread of T total (S<U<T)
- If there are any selected articles, the information between the
- brackets will be high-lighted (to show that something is selected, but
- not all the unread articles).
-
- The current presentation is a compromise between keeping the `look and
- feel' of a closed subject as close to existing customs in the normal
- cases, and at the same time give as much information in as little
- space as possible in the lesser frequent cases. Personally, I think
- it is a bit messy, so I am very interested in how you feel about it.
-
- Notice: Consolidated menus only work with the `subject' and `lexical'
- sorting modes.
-
- Variables related to consolidated menus are:
-
- consolidated-menu boolean = off turn consolidation on and off.
-
- auto-select-closed integer = 1 how much should `x' select:
- 0: select root article only
- 1: select UNREAD articles only (select all if no unread)
- 2: select ALL articles.
-
- save-closed-mode integer = 13 how to save a closed subject `Sx':
- 0: save root article (the one on the menu) only
- 1: save selected articles within subject
- 2: save unread (excl selected) articles within subject
- 3: save selected+unread articles within subject
- 4: save all articles within subject
- 10+<value above>: ask what to do with <> as default choice.
-
- counter-delim-left string = "[" left delimiter on subject counter(s)
-
- counter-delim-right string = "] " right delimiter on subject counter(s)
-
- ----
-
- A few other features introduced in this patch are:
-
- There is a new variable influencing the look of the menu:
-
- menu-spacing integer = 0 add blank lines between menu lines:
- 0: no blank lines
- 1: add blank line between subjects (try this with open subjects)
- 2: add blank line between articles
-
-
- For all practical purposes, `.' {select} can now be used to reference
- the current article on the menu, specifically when nn asks " from
- article". E.g. to have ^Xk add the current subject to the kill file,
- the following macro can be defined:
-
- make map ctl-x # create keymap for ^X prefix
- map menu ^x prefix ctl-x # map ^X to the new keymap
-
- map ctl-x k (
- kill-select
- '^m' # (CR => kill subject for 30 days)
- select # current subject
- )
-
- As usual, all changes are described in the updated RELEASE_NOTES file
- (read that for more details about this patch). Thanks to all who
- reported bugs and provided fixes.
-
- To apply this patch, use nn's :patch command, or run this command from
- the shell in the root of the nn source tree:
- patch -p0 < this-article
-
- Then run "make all" and "./inst u".
-
- ++Kim Storm
-
- ===================================================================
-
- *** ./LAST/data.h Wed May 2 23:10:48 1990
- --- data.h Thu Apr 11 22:11:26 1991
- ***************
- *** 152,163 ****
- char * sender; /* sender's name */
- char * subject; /* subject (w/o Re:) */
-
- - int16 replies; /* no of Re: */
- int16 lines; /* no of lines */
-
- int8 subj_length; /* length of subject */
- int8 name_length; /* length of sender */
-
- attr_type attr; /* attributes: */
- attr_type disp_attr; /* currently displayed attr. */
- /* warning: notice relation between A_SELECT and A_AUTO_SELECT */
- --- 152,165 ----
- char * sender; /* sender's name */
- char * subject; /* subject (w/o Re:) */
-
- int16 lines; /* no of lines */
- + int8 replies; /* no of Re: */
-
- int8 subj_length; /* length of subject */
- int8 name_length; /* length of sender */
-
- + int8 menu_line; /* current line on menu */
- +
- attr_type attr; /* attributes: */
- attr_type disp_attr; /* currently displayed attr. */
- /* warning: notice relation between A_SELECT and A_AUTO_SELECT */
- ***************
- *** 177,182 ****
- --- 179,185 ----
-
- # define A_SAME FLAG(1) /* same subject as prev. article */
- # define A_ALMOST_SAME FLAG(2) /* A_SAME (match-limit) */
- + # define A_ROOT_ART FLAG(3) /* root article in subject */
- # define A_NEXT_SAME FLAG(4) /* next is same subject */
- # define A_DIGEST FLAG(5) /* digest sub article */
- # define A_FULL_DIGEST FLAG(6) /* full digest */
- ***************
- *** 185,190 ****
- --- 188,195 ----
- # define A_ST_FILED FLAG(10) /* articles is saved */
- # define A_ST_REPLY FLAG(11) /* sent reply to article */
- # define A_ST_FOLLOW FLAG(12) /* sent followup to article */
- + # define A_CLOSED FLAG(13) /* subject closed on menu */
- + # define A_HIDE FLAG(14) /* hide subject on menu */
-
- } article_header;
-
- *** ./LAST/doc/RELEASE_NOTES Thu Apr 11 23:42:48 1991
- --- doc/RELEASE_NOTES Thu Apr 11 23:50:53 1991
- ***************
- *** 1534,1540 ****
- --- 1534,1553 ----
- From: Michael Schwager <schwager@cs.uiuc.edu>
- Fixed: Patch #14 [newsrc.c]
-
- + Prog: nn
- + Title: Current article can now be select by `.' when asked "... from article"
- + From: farrell@batserver.cs.uq.oz.au (Friendless)
- + Fixed: Patch #15 [menu.c]
- +
- + Specifically, `K CR .' would not kill the current article.
- + The fix allows `.' {select} everywhere an article id can be entered.
- +
- + Prog: nn
- + Title: Should adjust number of unread articles so "1 of 20/1" is avoided.
- + From: meulenbr@cst.philips.nl (Frans Meulenbroeks)
- + Fixed: Patch #15 [menu.c]
-
- +
- New features since initial 6.4.0 release
- ----------------------------------------
-
- ***************
- *** 2064,2066 ****
- --- 2077,2089 ----
- Added: Patch #14 [answer.c config.h-dist]
-
- Simply define NNTP_PATH_HOSTNAME as the path of the file.
- +
- + Prog: nn
- + Title: Added "consolidated menus" (one menu line per subject)
- + From: KFS on numerous requests
- + Added: Patch #15 [data.h group.c keymap.c/.h menu.c sort.c variable.c nn.1]
- +
- + Prog: nn
- + Title: Blank lines can now be added between menu lines via `menu-spacing'.
- + From: KFS on request from salsbury@acsu.buffalo.edu (Patrick G. Salsbury)
- + Added: Patch #15 [menu.c variable.c nn.1]
- *** ./LAST/folder.c Wed Feb 6 19:14:17 1991
- --- folder.c Thu Apr 11 22:27:04 1991
- ***************
- *** 503,509 ****
- goto move_back;
- }
-
- ! sort_articles(0);
-
- printf("\rCompressing folder...\n\r"); fl;
-
- --- 503,509 ----
- goto move_back;
- }
-
- ! sort_articles(-2);
-
- printf("\rCompressing folder...\n\r"); fl;
-
- *** ./LAST/group.c Thu Apr 11 22:05:34 1991
- --- group.c Thu Apr 11 22:27:04 1991
- ***************
- *** 356,362 ****
- if (access_mode & ACC_ALSO_READ_ARTICLES || first_art >= 0) continue;
- if (menu_cmd != ME_NO_ARTICLES) gh->group_flag &= ~G_NEW;
- if (gh->group_flag & G_UNSUBSCRIBED && !keep_unsub_long) continue;
- ! if (n) sort_articles(0);
- n = 0;
- update_rc(gh);
- rc_merged_groups_hack = 1;
- --- 356,362 ----
- if (access_mode & ACC_ALSO_READ_ARTICLES || first_art >= 0) continue;
- if (menu_cmd != ME_NO_ARTICLES) gh->group_flag &= ~G_NEW;
- if (gh->group_flag & G_UNSUBSCRIBED && !keep_unsub_long) continue;
- ! if (n) sort_articles(-2);
- n = 0;
- update_rc(gh);
- rc_merged_groups_hack = 1;
- ***************
- *** 448,453 ****
- --- 448,454 ----
- extern group_header *jump_to_group;
- article_number o_cur_first = -1;
- group_header *read_mode_group;
- + extern int bypass_consolidation;
-
- #define goto_return( cmd ) \
- { menu_cmd = cmd; goto goto_exit; }
- ***************
- *** 848,853 ****
- --- 849,855 ----
- if (ah == NULL) goto_return(ME_NO_REDRAW);
- strncpy(mask, (access_mode & ACC_ON_SUBJECT) ? ah->subject : ah->sender, GET_S_BUFFER);
- mask[GET_S_BUFFER-1] = NUL;
- + bypass_consolidation = 1;
- }
-
- if (*mask) {
- ***************
- *** 860,865 ****
- --- 862,868 ----
- m_endinput();
- if (o_cur_first < 0) o_cur_first = gh->current_first;
- menu_cmd = group_menu(gh, first, access_mode, mask, menu);
- + bypass_consolidation = 0; /* in case no articles were found */
- release_memory(&mem_marker);
-
- goto_exit:
- *** ./LAST/keymap.c Wed Nov 7 15:54:33 1990
- --- keymap.c Thu Apr 11 22:11:28 1991
- ***************
- *** 330,337 ****
- /* % */ K_PREVIEW,
- /* & */ K_UNBOUND,
- /* ' */ K_UNBOUND,
- ! /* ( */ K_UNBOUND,
- ! /* ) */ K_UNBOUND,
- /* * */ K_SELECT_SUBJECT,
- /* + */ K_AUTO_SELECT,
- /* , */ K_NEXT_LINE,
- --- 330,337 ----
- /* % */ K_PREVIEW,
- /* & */ K_UNBOUND,
- /* ' */ K_UNBOUND,
- ! /* ( */ K_OPEN_SUBJECT,
- ! /* ) */ K_CLOSE_SUBJECT,
- /* * */ K_SELECT_SUBJECT,
- /* + */ K_AUTO_SELECT,
- /* , */ K_NEXT_LINE,
- ***************
- *** 453,458 ****
- --- 453,459 ----
- "back-group", K_BACK_GROUP, 0,
-
- "cancel", K_CANCEL, 0,
- + "close-subject", K_CLOSE_SUBJECT, K_ONLY_MENU,
- "command", K_EXTENDED_CMD, 0,
- "compress", K_COMPRESS, K_ONLY_MORE,
- "continue", K_CONTINUE, 0,
- ***************
- *** 490,495 ****
- --- 491,497 ----
- "next-subject", K_NEXT_SUBJECT, K_ONLY_MORE,
- "nil", K_UNBOUND, 0,
-
- + "open-subject", K_OPEN_SUBJECT, K_ONLY_MENU,
- "overview", K_GROUP_OVERVIEW, 0,
-
- "page+1", K_NEXT_PAGE, 0,
- *** ./LAST/keymap.h Mon Jul 9 17:59:56 1990
- --- keymap.h Thu Apr 11 22:11:28 1991
- ***************
- *** 99,104 ****
- --- 99,107 ----
-
- #define K_PREVIEW 0x004f /* preview article */
-
- + #define K_OPEN_SUBJECT 0x0050 /* open subject on menu */
- + #define K_CLOSE_SUBJECT 0x0051 /* close subject on menu */
- +
- #define K_EQUAL_KEY 0x0070 /* map command special symbol */
-
- #define K_MACRO 0x0100 /* call macro */
- *** ./LAST/man/nn.1.A Wed Nov 7 15:54:36 1990
- --- man/nn.1.A Thu Apr 11 23:53:53 1991
- ***************
- *** 352,357 ****
- --- 352,367 ----
- typical menu will thus only show each subject once, saving a lot of
- time in scanning the news articles.
- .LP
- + If \fIconsolidated menus\fP (see section below) are enabled, adjacent
- + articles sharing the same subject will be shown with a \fIsingle\fP
- + line on the menu corresponding to the \fIfirst\fP of the articles.
- + The number of articles with the same subject will be shown as a
- + braketed number in front of the subject, e.g. with layout 1:
- + .br
- + \fIx Name......... 123 [4] Subject..............\fP
- + .br
- + For further information see the section on consolidated menus below.
- + .LP
- \fBRelated variables\fP:
- collapse-subject, columns, confirm-entry, confirm-entry-limit,
- entry-report-limit, fsort, kill, layout, limit, lines, long-menu,
- ***************
- *** 664,669 ****
- --- 674,772 ----
- confirm-auto-quit, confirm-entry, confirm-junk-seen,
- marked-by-next-group, marked-by-read-return, marked-by-read-skip,
- retain-seen-status, select-on-sender.
- + .SH CONSOLIDATED MENUS
- + Normally, \fInn\fP will use one menu line for each article, so if
- + there are many articles with identical subjects, each menu page will
- + only contain a few different subjects. To have each subject occur
- + only once on the menu, \fInn\fP can operate with consolidated menus by
- + setting the variable \fBconsolidated-menu\fP.
- + .LP
- + When consolidated menus are used, \fInn\fP operates with two kinds of
- + subjects: open and closed.
- + .LP
- + An \fIopen subject\fP is a subject which is shown in the traditional way
- + with one menu line for each article with the given subject. In other
- + words, when consolidated menus are not used, all subjects are open (by
- + default).
- + .LP
- + A \fIclosed subject\fP is a multi-article subject which is presented
- + by a single menu line. This line will be the normal menu line for the
- + first (oldest) article with the subject, but with the subject field
- + annotated with a bracketed number showing the number of articles with
- + that subject, e.g.
- + .sp 0.5v
- + a Kim F. Storm 12 [4] Future plans for nn
- + .br
- + b.Kim F. Storm 43 [3] More plans for nn
- + .sp 0.5v
- + In this example, there are four unread articles with subject `a' of
- + which the first is posted by me and has 12 lines. The rest of the
- + articles are hidden, and will only be shown on request. The `.'
- + marker on subject `b' shows that all three articles within that
- + subject have been read (or seen).
- + .LP
- + To select (or deselect) ALL the articles within a closed subject,
- + simply select the article shown on the menu; this will automatically
- + select (or deselect) the rest (see auto-select-closed). When all the
- + unread articles within a closed subject are selected, the menu line
- + will be high-lighted.
- + .LP
- + If you want to view the individual articles in a subject (maybe to
- + select individual articles), you can open the subject with the
- + commands:
- + .TP
- + \fB(x\fP
- + Open subject \fIx\fP on menu.
- + .TP
- + \fB((\fP
- + Open current subject.
- + .LP
- + When you have completed viewing the opened subject, you can close it
- + again using the commands:
- + .TP
- + \fB)x\fP
- + Close subject \fIx\fP on menu (\fIx\fP is any article with the subject).
- + .TP
- + \fB))\fP
- + Close current subject.
- + .LP
- + In the basic layout of the menu line for a closed subject as shown
- + above, ALL articles in the closed subject are supposed to be either:
- + .TP
- + \fIunread\fP
- + The menu line is \fInot\fP high-lighted.
- + .TP
- + \fIselected\fP
- + Menu line is fully high-lighted (if all UNREAD are selected).
- + .TP
- + \fBread/seen\fP
- + There is a `.' (read attribute) following the article id.
- + .LP
- + If neither of these cases apply, i.e. there is a mixture of unread,
- + selected, and seen/read articles, the bracketed number will have one
- + of the following formats:
- + .TP
- + [U:T]
- + There are U unread articles of T total (U<T).
- + .TP
- + [S/T]
- + There are S selected articles of T total (S<U=T).
- + .TP
- + [S/U:T]
- + There are S selected of U unread of T total (S<U<T).
- + .LP
- + If there are any selected articles (S>0), the information between the
- + brackets will be high-lighted (to show that something is selected, but
- + not all the unread articles).
- + .LP
- + \fBNotice\fP: Consolidated menus only work with the `subject' and
- + `lexical' sorting methods.
- + .LP
- + Variables related to consolidated menus are:
- + auto-select-closed,
- + consolidated-menu,
- + counter-delim-left, counter-delim-right,
- + save-closed-mode.
- .SH THE JUNK-ARTICLES AND LEAVE-NEXT COMMANDS
- The \fBJ\fP {\fBjunk-articles\fP} command is a very flexible command
- which can perform all sorts of attribute changes, either on individual
- *** ./LAST/man/nn.1.C Thu Apr 11 22:05:37 1991
- --- man/nn.1.C Thu Apr 11 23:53:53 1991
- ***************
- *** 245,250 ****
- --- 245,261 ----
- conditionally if the value is greater than zero and the number of
- unread articles in the current group does not exceed the given value.
- .TP
- + \fBauto-select-closed\fP \fImode\fP (integer, default 1)
- + Normally, selecting a \fIclosed subject\fP (usually in consolidated
- + menu mode) will select (or deselect) all \fIunread\fP articles with
- + the given subject (or all articles if they are all read). This
- + behaviour can be changed via the value of this variable as follows:
- + .nf
- + 0: select only the first article with the subject (shown on menu).
- + 1: select only the unread articles with the subject.
- + 2: select all available articles with the subject.
- + .fi
- + .TP
- \fBauto-select-subject\fP (boolean, default false)
- When set, selecting an article from the menu using the article id
- (a-z), all articles on the menu with the same subject will
- ***************
- *** 365,370 ****
- --- 376,394 ----
- key. (It will show the symbol <> to indicate that it is awaiting
- confirmation.)
- .TP
- + \fBconsolidated-menu\fP (boolean, default false)
- + When set, \fInn\fP will automatically \fIclose\fP all multi-article
- + subjects on entry to a group, so that each subject only occur once on
- + the menu page.
- + .TP
- + \fBcounter-delim-left\fP (string, default "[")
- + The delimiter string output to the left of the article counter in a
- + closed subject's menu line.
- + .TP
- + \fBcounter-delim-right\fP (string, default "] ")
- + The delimiter string output to the right of the article counter in a
- + closed subject's menu line.
- + .TP
- \fBcross-filter-seq\fP (boolean, default true)
- When set, cross posted articles will be presented in the first
- possible group, i.e. according to the current presentation sequence
- ***************
- *** 804,809 ****
- --- 828,844 ----
- the underline attribute). This is typically used to give overlapping
- lines a different colour on terminals which have this capability.
- .TP
- + \fBmenu-spacing\fP \fImode\fP (integer, default 0)
- + When \fImode\fP is a non-zero number as described below, \fInn\fP will
- + add blank lines between the lines on the menu to increase readability
- + at the cost of presenting fewer articles on each page. The following
- + values of \fImode\fP are recognized:
- + .nf
- + 0: Don't add blank lines between menu lines.
- + 1: Add a blank line between articles with \fIdifferent\fP subjects.
- + 2: Add a blank line between \fIall\fP articles.
- + .fi
- + .TP
- \fBmessage-history\fP \fIN\fP (integer, default 15)
- Specifies the maximum number, \fIN\fP, of older messages which can be
- recalled with the \fB^P\fP {\fBmessage\fP} command.
- ***************
- *** 1110,1115 ****
- --- 1145,1167 ----
- When set, \fInn\fP will try the specified number of \fItimes\fP to
- open an article before reporting that the article does not exist
- any more. This may be necessary in some network environments.
- + .TP
- + \fBsave-closed-mode\fP \fImode\fP (integer, default 13)
- + When saving an article in selection mode (i.e. by selecting it from
- + the menu), \fInn\fP will simply save the specified article if the
- + article's subject is \fIopen\fP. When the selected menu entry is a
- + closed subject, the \fBsave-closed-mode\fP variable determines how
- + many articles among the closed articles should be saved:
- + .nf
- + 0: save root article (the one on the menu) only
- + 1: save selected articles within subject
- + 2: save unread (excl selected) articles within subject
- + 3: save selected+unread articles within subject
- + 4: save all articles within subject
- + .fi
- + If `10' is added to the above values, \fInn\fP will not save the
- + selected subject immediately; instead it will ask which articles
- + to save using the above value as the default answer.
- .TP
- \fBsave-counter\fP \fIformat\fP (string, default "%d")
- This is the printf-format which \fInn\fP uses to create substitution
- *** ./LAST/menu.c Thu Jul 19 18:12:19 1990
- --- menu.c Thu Apr 11 22:11:32 1991
- ***************
- *** 31,36 ****
- --- 31,43 ----
- export int show_purpose_mode = 1; /* 0: never, 1: new, 2: always */
- export int read_ret_next_page = 0; /* Z returns to next page */
-
- + export int consolidated_menu = 0; /* show only root articles */
- + export int save_closed_mode = 13; /* ask how to save closed subj, dflt all */
- + export int auto_select_closed = 1; /* select all in closed subject */
- + export int menu_spacing = 0; /* number of screen lines per menu line */
- + export char *counter_delim_left = "[";
- + export char *counter_delim_right = "] ";
- +
- export int auto_preview_mode = 0; /* preview rather than select */
- export int preview_continuation = 12; /* what to do after preview */
- export int preview_mark_read = 1; /* previewed articles are A_READ */
- ***************
- *** 66,71 ****
- --- 73,93 ----
-
- char attributes[30] = " .,+=#! **"; /* Corresponds to A_XXXX in data.h */
-
- + static int menu_length; /* current no of line on menu */
- + static int menu_articles; /* current no of articles on menu */
- +
- + static struct menu_info { /* info for each menu line */
- + int mi_cura; /* cura corresponding to this menu line */
- + int mi_total; /* total number of articles with this subject */
- + int mi_unread; /* no of unread articles with this subject */
- + int mi_selected; /* no of selected articles with this subject */
- + int mi_art_id; /* article id (for mark()) */
- + } menu_info[INTERVAL1+INTERVAL2];
- +
- + static struct menu_info *art_id_to_mi[INTERVAL1+INTERVAL2];
- +
- + #define IS_VISIBLE(ah) (((ah)->flag & (A_CLOSED | A_ROOT_ART)) != A_CLOSED)
- +
- prt_replies(level)
- {
- int re;
- ***************
- *** 107,130 ****
- return 11;
- }
-
- static mark()
- {
- register article_header *ah;
- int lno, lnum, lsubj, lname;
-
- ah = articles[firsta + cura];
- last_attr = ah->attr;
-
- - if (last_attr == ah->disp_attr) return;
- if (cura < 0 || cura > numa) return;
-
- ! lno = firstl + cura;
- ! if (ah->disp_attr == A_NOT_DISPLAYED) {
- ! gotoxy(0, lno);
- ! putchar(ident[cura]);
- goto print_line;
- }
-
- /* A_AUTO_SELECT will not occur here! */
-
- if (!slow_mode)
- --- 129,250 ----
- return 11;
- }
-
- + static article_number root_article(root)
- + register article_number root;
- + {
- + register article_header *ah = articles[root];
- +
- + if (ah->flag & A_ROOT_ART)
- + return root;
- +
- + if (ah->flag & A_CLOSED) /* only root article is shown on menu */
- + return firsta + menu_info[ah->menu_line].mi_cura;
- +
- + while (root > 0) {
- + if (articles[root]->flag & A_ROOT_ART) break;
- + root--;
- + }
- + return root;
- + }
- +
- + static article_number next_root_article(root)
- + register article_number root;
- + {
- + while (++root < n_articles)
- + if (articles[root]->flag & A_ROOT_ART) break;
- + return root;
- + }
- +
- + static set_root_if_closed()
- + {
- + if (articles[firsta + cura]->flag & A_CLOSED)
- + cura = root_article(firsta + cura) - firsta;
- + }
- +
- + /*
- + * count info for thread containing article #art (must be on menu!)
- + * returns article number for next root article
- + */
- +
- + static article_number thread_counters(art)
- + article_number art;
- + {
- + register struct menu_info *mi;
- + register article_number n;
- + int total, unread, selected, invisible;
- +
- + if (!(articles[art]->flag & A_CLOSED)) return art + 1;
- +
- + total = unread = selected = 0;
- + n = art = root_article(art);
- +
- + while (n < n_articles) {
- + if (articles[n]->attr == 0) unread++;
- + else if (articles[n]->attr & A_SELECT) selected++;
- + total++;
- + if (++n == n_articles) break;
- + if (articles[n]->flag & A_ROOT_ART) break;
- + }
- + unread += selected;
- +
- + mi = menu_info + articles[art]->menu_line;
- + mi->mi_total = total;
- + mi->mi_unread = unread;
- + mi->mi_selected = selected;
- + return n;
- + }
- +
- + static cursor_at_id()
- + {
- + gotoxy(0, firstl + articles[firsta + cura]->menu_line);
- + fl; /* place cursor at current article id */
- + save_xy();
- + }
- +
- static mark()
- {
- register article_header *ah;
- + register struct menu_info *mi;
- int lno, lnum, lsubj, lname;
- + int only_counters;
- + char cbuf[80];
- + attr_type cattr;
-
- ah = articles[firsta + cura];
- + if (!IS_VISIBLE(ah)) return;
- +
- last_attr = ah->attr;
- + if (ah->disp_attr == A_NOT_DISPLAYED) {
- + mi = &menu_info[ah->menu_line];
- + lno = firstl + ah->menu_line;
- + gotoxy(0, lno);
- + putchar(ident[mi->mi_art_id]);
- + only_counters = 0;
- + goto print_line;
- + }
-
- if (cura < 0 || cura > numa) return;
-
- ! lno = firstl + ah->menu_line;
- !
- ! if (ah->flag & A_CLOSED) {
- ! struct menu_info old;
- ! mi = &menu_info[ah->menu_line];
- ! old = *mi;
- ! thread_counters(firsta + cura);
- ! if (old.mi_total == mi->mi_total &&
- ! old.mi_selected == mi->mi_selected &&
- ! old.mi_unread == mi->mi_unread) return;
- !
- ! if (old.mi_total == old.mi_selected)
- ! only_counters = mi->mi_total == mi->mi_selected;
- ! else
- ! only_counters = mi->mi_total != mi->mi_selected;
- goto print_line;
- }
-
- + if (last_attr == ah->disp_attr) return;
- +
- /* A_AUTO_SELECT will not occur here! */
-
- if (!slow_mode)
- ***************
- *** 150,163 ****
- 4 id subject (or as 1 if short subject)
- */
-
- if (fmt_linenum > 4) fmt_linenum = 1;
-
- ! if (!slow_mode && (ah->attr & A_SELECT)) {
- if (so_gotoxy(1, lno, 1) == 0)
- putchar(attributes[A_SELECT]);
- } else {
- gotoxy(1, lno);
- ! putchar(attributes[ah->attr]);
- }
-
- if (ah->lines < 10) lnum = 1; else
- --- 270,307 ----
- 4 id subject (or as 1 if short subject)
- */
-
- + cattr = ah->attr;
- + cbuf[0] = NUL;
- + if (ah->flag & A_CLOSED) {
- + char sel[10], unr[10];
- +
- + if (mi->mi_unread == 0)
- + cattr = A_READ;
- + else if (mi->mi_total == mi->mi_selected)
- + cattr = A_SELECT;
- + else if (auto_select_closed == 1 && mi->mi_unread == mi->mi_selected)
- + cattr = A_SELECT;
- + else if (mi->mi_selected)
- + cattr = A_KILL; /* pseudo flag -> highlight cbuf */
- + else
- + cattr = 0;
- +
- + sel[0] = unr[0] = NUL;
- + if (mi->mi_selected && mi->mi_selected < mi->mi_unread)
- + sprintf(sel, "%d/", mi->mi_selected);
- + if (mi->mi_unread && mi->mi_unread < mi->mi_total)
- + sprintf(unr, "%d:", mi->mi_unread);
- + sprintf(cbuf, "%s%s%d", sel, unr, mi->mi_total);
- + }
- +
- if (fmt_linenum > 4) fmt_linenum = 1;
-
- ! if (!slow_mode && (cattr & A_SELECT)) {
- if (so_gotoxy(1, lno, 1) == 0)
- putchar(attributes[A_SELECT]);
- } else {
- gotoxy(1, lno);
- ! putchar(cattr == A_KILL ? ' ' : attributes[cattr]);
- }
-
- if (ah->lines < 10) lnum = 1; else
- ***************
- *** 205,210 ****
- --- 349,364 ----
- break;
- }
-
- + print_subj:
- + if (cbuf[0]) {
- + so_printf("%s", counter_delim_left);
- + if (cattr == A_KILL) so_gotoxy(-1, -1, 0);
- + so_printf("%s", cbuf);
- + if (cattr == A_KILL) so_end();
- + so_printf("%s", counter_delim_right);
- + lsubj -= strlen(cbuf) + strlen(counter_delim_left) + strlen(counter_delim_right);
- + }
- +
- if (!fmt_rptsubj && lno > firstl && ah->flag & A_SAME) {
- if (ah->replies == 0 || prt_replies(ah->replies) == 0)
- so_printf("-");
- ***************
- *** 227,232 ****
- --- 381,387 ----
- so_printf(ah->lines >= 0 ? " +%d" : " +?", ah->lines);
-
- so_end();
- + if (ah->flag & A_CLOSED) clrline();
-
- out:
- ah->disp_attr = last_attr;
- ***************
- *** 280,288 ****
- --- 435,448 ----
- if (!kill_file_loaded && !init_kill()) return 0;
-
- o_cura = cura;
- + cura = -1;
-
- for (i = 0, ahp = articles; i < n_articles; i++, ahp++) {
- ah = *ahp;
- + if (cura >= 0 && (ah->flag & A_ROOT_ART)) {
- + mark();
- + cura = -1;
- + }
- if (re != NULL) {
- if (!regexec_cf(re, select_on_sender ? ah->sender : ah->subject)) continue;
- } else
- ***************
- *** 290,302 ****
-
- count++;
- if (ah->attr & A_SELECT) continue;
- if (firsta <= i && i <= (firsta+numa)) {
- cura = i - firsta;
- ! new_mark(A_SELECT);
- ! } else
- ! ah->attr = A_SELECT;
- }
-
- if (count)
- msg("Selected %d article%s", count, plural((long)count));
- else
- --- 450,467 ----
-
- count++;
- if (ah->attr & A_SELECT) continue;
- + ah->attr = A_SELECT;
- if (firsta <= i && i <= (firsta+numa)) {
- cura = i - firsta;
- ! if ((ah->flag & A_CLOSED) == 0) {
- ! mark();
- ! cura = -1;
- ! }
- ! }
- }
-
- + if (cura >= 0) mark();
- +
- if (count)
- msg("Selected %d article%s", count, plural((long)count));
- else
- ***************
- *** 320,326 ****
- case 1:
- return 0;
- case 2:
- ! return (articles[firsta+cura]->flag & (A_SAME | A_ALMOST_SAME)) == 0;
- }
- return 0;
- }
- --- 485,491 ----
- case 1:
- return 0;
- case 2:
- ! return articles[firsta+cura]->flag & A_ROOT_ART;
- }
- return 0;
- }
- ***************
- *** 404,410 ****
- case MC_NEXTSUBJ:
- ah->attr = A_READ;
- for (next = cur+1; next < n_articles; next++) {
- ! if (((ah = articles[next])->flag & (A_SAME | A_ALMOST_SAME)) == 0) break;
- ah->attr = A_READ;
- }
- for (; next < n_articles; next++) {
- --- 569,575 ----
- case MC_NEXTSUBJ:
- ah->attr = A_READ;
- for (next = cur+1; next < n_articles; next++) {
- ! if ((ah = articles[next])->flag & A_ROOT_ART) break;
- ah->attr = A_READ;
- }
- for (; next < n_articles; next++) {
- ***************
- *** 416,422 ****
- ah->attr = A_READ;
- for (next = cur+1; next < n_articles; next++) {
- ah = articles[next];
- ! if ((ah->flag & (A_SAME | A_ALMOST_SAME)) == 0) break;
- ah->attr = A_SELECT;
- }
- for (next = cur+1; next < n_articles; next++)
- --- 581,587 ----
- ah->attr = A_READ;
- for (next = cur+1; next < n_articles; next++) {
- ah = articles[next];
- ! if (ah->flag & A_ROOT_ART) break;
- ah->attr = A_SELECT;
- }
- for (next = cur+1; next < n_articles; next++)
- ***************
- *** 494,499 ****
- --- 659,665 ----
-
- static int article_id;
- static int cur_key;
- + static int is_k_select; /* set when K_ARTICLE_ID was really K_SELECT */
-
- static int get_k_cmd_1()
- {
- ***************
- *** 522,535 ****
- goto loop;
- }
-
- if (map & K_ARTICLE_ID) {
- article_id = map & ~K_ARTICLE_ID;
- map = K_ARTICLE_ID;
-
- ! if (article_id < 0 || article_id > numa) {
- ding();
- goto loop;
- }
- }
-
- if (any_message && map != K_LAST_MESSAGE) clrmsg(-1);
- --- 688,708 ----
- goto loop;
- }
-
- + is_k_select = 0;
- + if (map == K_SELECT) {
- + map = K_ARTICLE_ID;
- + article_id = cura;
- + is_k_select = 1;
- + } else
- if (map & K_ARTICLE_ID) {
- article_id = map & ~K_ARTICLE_ID;
- map = K_ARTICLE_ID;
-
- ! if (article_id < 0 || article_id > menu_articles) {
- ding();
- goto loop;
- }
- + article_id = art_id_to_mi[article_id]->mi_cura;
- }
-
- if (any_message && map != K_LAST_MESSAGE) clrmsg(-1);
- ***************
- *** 575,591 ****
- int update;
- {
- int any;
-
- if (new == old) return 0;
- if (new == A_KILL) update = 0;
-
- any = 0;
- while (first < last) {
- ! if (old == A_KILL || articles[first]->attr == old) {
- ! articles[first]->attr = new;
- ! if (update) {
- ! cura = first-firsta;
- ! mark();
- }
- any = 1;
- }
- --- 748,776 ----
- int update;
- {
- int any;
- + register article_header *ah;
- + article_number ocura = cura;
-
- if (new == old) return 0;
- if (new == A_KILL) update = 0;
-
- any = 0;
- + cura = -1;
- while (first < last) {
- ! ah = articles[first];
- ! if (cura >= 0 && ah->flag & A_ROOT_ART) {
- ! set_root_if_closed();
- ! mark();
- ! cura = -1;
- ! }
- ! if (old == A_KILL || ah->attr == old) {
- ! ah->attr = new;
- ! if (update && first >= firsta && first < nexta) {
- ! cura = first - firsta;
- ! if ((ah->flag & A_CLOSED) == 0) {
- ! mark();
- ! cura = -1;
- ! }
- }
- any = 1;
- }
- ***************
- *** 592,600 ****
- --- 777,798 ----
-
- first++;
- }
- +
- + if (cura >= 0) {
- + set_root_if_closed();
- + mark();
- + }
- + cura = update ? last - firsta : ocura;
- return any;
- }
-
- + static repl_attr_subject(old, new, update)
- + attr_type old, new;
- + int update;
- + {
- + return repl_attr(root_article(firsta+cura), next_root_article(firsta+cura),
- + old, new, update);
- + }
-
- static repl_attr_all(old, new, update)
- attr_type old, new;
- ***************
- *** 631,636 ****
- --- 829,878 ----
- }
- }
-
- + /*
- + * bypass_consolidation may be set to temporarily overrule the global
- + * consolidated_menu variable:
- + * 1: don't consolidate (e.g. for G=... )
- + * 2: do consolidate
- + * 3: use consolidated_mode
- + */
- +
- + export int bypass_consolidation = 0;
- + static int cur_bypass = 0; /* current bypass status (see below) */
- +
- + static do_consolidation()
- + {
- + int consolidate;
- +
- + switch (bypass_consolidation) {
- + case 0:
- + break;
- + case 1:
- + cur_bypass = -1; /* no consolidation */
- + break;
- + case 2:
- + cur_bypass = 1; /* force consolidation */
- + break;
- + case 3:
- + cur_bypass = 0; /* reset bypass to use consolidated_menu */
- + break;
- + }
- + bypass_consolidation = 0;
- +
- + if (cur_bypass)
- + consolidate = cur_bypass > 0;
- + else
- + consolidate = consolidated_menu;
- +
- + if (consolidate)
- + for (nexta = 0; nexta < n_articles; nexta++)
- + articles[nexta]->flag |= A_CLOSED;
- + else
- + for (nexta = 0; nexta < n_articles; nexta++)
- + articles[nexta]->flag &= ~A_CLOSED;
- +
- + return consolidate;
- + }
-
- menu(print_header)
- fct_type print_header;
- ***************
- *** 637,642 ****
- --- 879,886 ----
- {
- register k_cmd, cur_k_cmd;
- register article_header *ah;
- + register struct menu_info *mi;
- + int consolidate, o_bypass;
- int last_k_cmd;
- int menu_cmd, temp;
- int save_selected;
- ***************
- *** 670,675 ****
- --- 914,925 ----
- menu_level++;
-
- if (menu_level == 1) {
- + if ((current_group->group_flag & G_COUNTED)
- + && n_articles != current_group->unread_count) {
- + add_unread(current_group, -1);
- + current_group->unread_count = n_articles;
- + add_unread(current_group, 0);
- + }
- entry_check = conf_group_entry && n_articles > conf_entry_limit;
- auto_read = auto_read_limit < 0 || n_articles <= auto_read_limit;
- } else {
- ***************
- *** 691,698 ****
- --- 941,954 ----
- case 0: break;
- case 1: if ((current_group->group_flag & G_NEW) == 0) break;
- case 2: get_purpose(purpose);
- + if (purpose[0]) strcpy(delayed_msg, purpose);
- }
-
- + o_bypass = cur_bypass;
- + cur_bypass = 0;
- +
- + consolidate = do_consolidation();
- +
- firsta = 0;
- while (firsta < n_articles && articles[firsta]->attr == A_SEEN)
- firsta++;
- ***************
- *** 768,800 ****
- gotoxy(0, firstl);
- clrpage(firstl);
-
- ! if (nexta > 0) {
- ! firsta = nexta;
- ! } else
- ! if (purpose[0]) {
- ! msg(purpose);
- ! }
- !
- firsta = nexta;
- - numa = Lines; /* for mark; is set correctly below */
- cura = 0;
-
- REDRAW_CHECK;
-
- ! if (!s_keyboard)
- ! while (nexta < n_articles && cura < maxa) {
- REDRAW_CHECK;
-
- ! articles[firsta+cura]->disp_attr = A_NOT_DISPLAYED;
- mark();
- ! nexta++; cura++;
- }
-
- fl;
- s_keyboard = 0;
-
- ! prompt_line = firstl + cura;
- ! if (!long_menu || cura < maxa) prompt_line++;
-
- numa = nexta - firsta - 1;
- if (numa < 0) prompt_line++;
- --- 1024,1106 ----
- gotoxy(0, firstl);
- clrpage(firstl);
-
- ! if (articles[nexta]->flag & A_CLOSED)
- ! nexta = root_article(nexta);
- firsta = nexta;
- cura = 0;
-
- REDRAW_CHECK;
-
- ! menu_length = 0;
- ! menu_articles = 0;
- ! goto draw_menu;
- !
- ! partial_redraw:
- ! next_cura = cura;
- ! partial_redraw_nc:
- ! nexta = firsta + cura;
- ! menu_length = articles[nexta]->menu_line;
- ! menu_articles = menu_info[menu_length].mi_art_id;
- ! gotoxy(0, firstl + menu_length);
- ! clrpage(firstl + menu_length);
- !
- ! draw_menu:
- ! if (!s_keyboard) {
- ! int first_menu_line = menu_length;
- !
- ! mi = menu_info + menu_length;
- ! while (nexta < n_articles) {
- REDRAW_CHECK;
-
- ! ah = articles[nexta];
- ! if (ah->flag & A_HIDE) {
- ! ah->menu_line = menu_length; /* just in case.... */
- ! continue;
- ! }
- ! if (menu_length > first_menu_line) {
- ! switch (menu_spacing) {
- ! case 0:
- ! break;
- ! case 1:
- ! if ((ah->flag & A_ROOT_ART) == 0) break;
- ! case 2:
- ! menu_length++;
- ! mi++;
- ! break;
- ! }
- ! if (menu_length >= maxa) break;
- ! }
- !
- ! ah->menu_line = menu_length;
- ! art_id_to_mi[menu_articles] = mi;
- ! mi->mi_art_id = menu_articles++;
- !
- ! mi->mi_cura = cura = nexta - firsta;
- ! if (ah->flag & A_CLOSED) { /* skip rest of thread */
- ! nexta = thread_counters(nexta);
- ! if (nexta == firsta + cura + 1)
- ! ah->flag &= ~A_CLOSED;
- ! else {
- ! article_number tmpa = firsta + cura;
- ! while (++tmpa < nexta)
- ! articles[tmpa]->menu_line = menu_length;
- ! }
- ! } else
- ! nexta++;
- ! ah->disp_attr = A_NOT_DISPLAYED;
- mark();
- ! if (++menu_length >= maxa) break;
- ! mi++;
- }
- + }
-
- + if (menu_length > maxa) menu_length = maxa;
- +
- fl;
- s_keyboard = 0;
-
- ! prompt_line = firstl + menu_length;
- ! if (!long_menu || menu_length < maxa) prompt_line++;
-
- numa = nexta - firsta - 1;
- if (numa < 0) prompt_line++;
- ***************
- *** 801,811 ****
- --- 1107,1123 ----
-
- if (next_cura >= 0) {
- cura = next_cura;
- + set_root_if_closed();
- next_cura = -1;
- } else {
- cura = 0;
- for (article_id = firsta; cura < numa; article_id++, cura++)
- + {
- if ((articles[article_id]->attr & A_SELECT) == 0) break; /*???*/
- + if (!IS_VISIBLE(articles[article_id])) continue;
- + }
- + if (!IS_VISIBLE(articles[article_id]))
- + cura = root_article(article_id) - firsta;
- }
-
- build_prompt:
- ***************
- *** 824,835 ****
-
- same_prompt:
-
- if (cura < 0 || cura > numa) cura = 0;
-
- if (numa >= 0) {
- ! gotoxy(0, firstl + cura);
- ! fl; /* place cursor at current article id */
- ! save_xy();
- }
-
- last_k_cmd = cur_k_cmd;
- --- 1136,1148 ----
-
- same_prompt:
-
- + if (!IS_VISIBLE(articles[firsta+cura]))
- + cura = next_root_article(firsta + cura) - firsta;
- +
- if (cura < 0 || cura > numa) cura = 0;
-
- if (numa >= 0) {
- ! cursor_at_id();
- }
-
- last_k_cmd = cur_k_cmd;
- ***************
- *** 874,879 ****
- --- 1187,1193 ----
- goto same_prompt;
-
- case K_EXTENDED_CMD:
- + temp = consolidated_menu;
- switch (alt_command()) {
-
- case AC_UNCHANGED:
- ***************
- *** 887,894 ****
-
- case AC_REORDER:
- firsta = 0;
- ! /* fall thru */
- case AC_REDRAW:
- goto redraw;
-
- case AC_KEYCMD:
- --- 1201,1212 ----
-
- case AC_REORDER:
- firsta = 0;
- ! consolidate = do_consolidation();
- ! goto redraw;
- !
- case AC_REDRAW:
- + if (temp != consolidated_menu)
- + consolidate = do_consolidation();
- goto redraw;
-
- case AC_KEYCMD:
- ***************
- *** 944,950 ****
- last_save = firsta + numa;
- } else
- if (k_cmd == K_AUTO_SELECT) {
- ! save_selected = 2;
- cura = -firsta;
- article_id = 0;
- last_save = n_articles - 1;
- --- 1262,1268 ----
- last_save = firsta + numa;
- } else
- if (k_cmd == K_AUTO_SELECT) {
- ! save_selected = 1;
- cura = -firsta;
- article_id = 0;
- last_save = n_articles - 1;
- ***************
- *** 953,964 ****
- cura = article_id;
- article_id += firsta;
- last_save = article_id;
- } else
- break;
-
- for ( ; article_id <= last_save ; article_id++, cura++) {
- ah = articles[article_id];
- ! if (save_selected && (ah->attr & A_SELECT) == 0) continue;
-
- if (cur_k_cmd == K_CANCEL) {
- if (current_group->group_flag & G_FOLDER) {
- --- 1271,1337 ----
- cura = article_id;
- article_id += firsta;
- last_save = article_id;
- + if (articles[article_id]->flag & A_CLOSED) {
- + int n = save_closed_mode % 10;
- + int c;
- +
- + if (article_id == n_articles - 1)
- + goto save_it;
- + if (articles[article_id + 1]->flag & A_ROOT_ART)
- + goto save_it;
- +
- + if (save_closed_mode >= 10) {
- + prompt("\1%s thread\1 (r)oot (s)elected (u)nread (b)oth (a)ll (%c)",
- + savemode, "rsuba"[n]);
- + switch (get_c()) {
- + case 'r': n = 0; break;
- + case 's': n = 1; break;
- + case 'u': n = 2; break;
- + case 'b': n = 3; break;
- + case 'a': n = 4; break;
- + case SP:
- + case CR:
- + case NL: break;
- + default: ding(); goto Prompt;
- + }
- + }
- + switch (n) {
- + case 0: /* save root only */
- + break;
- + case 1: /* save all selected */
- + save_selected = 1;
- + break;
- + case 2: /* save all unread */
- + save_selected = 2;
- + break;
- + case 3: /* save all selected + unread */
- + save_selected = 3;
- + break;
- + case 4: /* save all articles */
- + break;
- + }
- + if (n) last_save = next_root_article(article_id) - 1;
- + save_selected |= 8; /* closed subject */
- + temp1 = cura;
- + }
- } else
- break;
-
- + save_it:
- for ( ; article_id <= last_save ; article_id++, cura++) {
- ah = articles[article_id];
- ! switch (save_selected & 0x3) {
- ! case 0:
- ! break;
- ! case 3:
- ! if (ah->attr == 0) break;
- ! case 1:
- ! if ((ah->attr & A_SELECT) == 0) continue;
- ! break;
- ! case 2:
- ! if (ah->attr == 0) break;
- ! continue;
- ! }
-
- if (cur_k_cmd == K_CANCEL) {
- if (current_group->group_flag & G_FOLDER) {
- ***************
- *** 999,1004 ****
- --- 1372,1382 ----
- mark();
- }
- }
- + if (save_selected & 8) {
- + save_selected = 0; /* select closed */
- + cura = temp1;
- + mark();
- + }
- }
-
- if (save_selected) cura = 0;
- ***************
- *** 1149,1159 ****
- --- 1527,1540 ----
- /* FALL THRU */
-
- case K_GOTO_GROUP:
- + temp1 = n_articles;
-
- switch (goto_group(k_cmd, (article_header *)NULL, (flag_type)0)) {
-
- case ME_REDRAW:
- firsta = 0;
- + if (temp1 != n_articles && consolidate)
- + consolidate = do_consolidation();
- goto redraw;
-
- case ME_NO_ARTICLES:
- ***************
- *** 1173,1178 ****
- --- 1554,1618 ----
- goto empty_menu_hack;
- }
-
- + case K_OPEN_SUBJECT:
- + if (numa < 0) goto nextmenu;
- + prompt("\1Open subject\1");
- +
- + k_cmd = get_k_cmd();
- + if (k_cmd != K_ARTICLE_ID) {
- + if (k_cmd != cur_k_cmd) goto Prompt;
- + article_id = cura;
- + }
- +
- + open_subject:
- + ah = articles[firsta+article_id];
- + if (!(ah->flag & A_CLOSED) ||
- + (ah->flag & (A_ROOT_ART | A_NEXT_SAME)) == A_ROOT_ART)
- + goto Prompt;
- +
- + cura = article_id = root_article(firsta + article_id) - firsta;
- + while (cura + firsta < n_articles) {
- + ah = articles[firsta+cura];
- + if (cura > article_id && ah->flag & A_ROOT_ART)
- + break;
- + ah->flag &= ~A_CLOSED;
- + cura++;
- + }
- + cura = article_id;
- + goto partial_redraw;
- +
- + case K_CLOSE_SUBJECT:
- + if (numa < 0) goto nextmenu;
- + prompt("\1Close subject\1");
- +
- + k_cmd = get_k_cmd();
- + if (k_cmd != K_ARTICLE_ID) {
- + if (k_cmd != cur_k_cmd) goto Prompt;
- + article_id = cura;
- + }
- +
- + ah = articles[firsta+article_id];
- + if ((ah->flag & A_CLOSED) ||
- + (ah->flag & (A_ROOT_ART | A_NEXT_SAME)) == A_ROOT_ART) {
- + cura = next_root_article(firsta + cura) - firsta;
- + goto Prompt;
- + }
- +
- + cura = article_id = root_article(firsta + article_id) - firsta;
- + while (cura + firsta < n_articles) {
- + ah = articles[firsta+cura];
- + if (cura > article_id && ah->flag & A_ROOT_ART)
- + break;
- + ah->flag |= A_CLOSED;
- + cura++;
- + }
- + cura = article_id;
- + next_cura = next_root_article(firsta + cura) - firsta;
- + if (cura >= 0) goto partial_redraw_nc;
- + articles[cura + firsta]->menu_line = articles[firsta]->menu_line;
- + firsta += cura;
- + goto redraw;
- +
- case K_LEAVE_NEXT:
- case K_JUNK_ARTICLES:
- junk_prompt = cur_k_cmd == K_JUNK_ARTICLES ? 1 : 5;
- ***************
- *** 1207,1213 ****
-
- junk_another:
- if (cura < 0 || cura > numa) cura = 0;
- ! gotoxy(0, firstl + cura); fl;
-
- switch (get_k_cmd()) {
- case K_JUNK_ARTICLES:
- --- 1647,1653 ----
-
- junk_another:
- if (cura < 0 || cura > numa) cura = 0;
- ! cursor_at_id();
-
- switch (get_k_cmd()) {
- case K_JUNK_ARTICLES:
- ***************
- *** 1216,1226 ****
-
- case K_ARTICLE_ID:
- cura = article_id;
- - case K_SELECT:
- if (junk_attr == A_KILL) junk_attr = A_READ;
- ! articles[firsta + cura]->attr = junk_attr;
- ! mark();
- ! cura++;
- goto junk_another;
-
- case K_NEXT_LINE:
- --- 1656,1669 ----
-
- case K_ARTICLE_ID:
- cura = article_id;
- if (junk_attr == A_KILL) junk_attr = A_READ;
- ! if (auto_select_closed > 0 && articles[firsta + cura]->flag & A_CLOSED)
- ! repl_attr_subject(A_KILL, junk_attr, 1);
- ! else {
- ! articles[firsta + cura]->attr = junk_attr;
- ! mark();
- ! cura++;
- ! }
- goto junk_another;
-
- case K_NEXT_LINE:
- ***************
- *** 1312,1325 ****
- case K_ARTICLE_ID:
- if (numa < 0) goto nextmenu;
-
- ! if (auto_preview_mode) goto auto_preview;
-
- cura = article_id;
- ! toggle();
- ! if (auto_select_subject) goto select_subject;
- ! mark();
- ! cura++;
-
- goto same_prompt;
-
- case K_SELECT_INVERT:
- --- 1755,1783 ----
- case K_ARTICLE_ID:
- if (numa < 0) goto nextmenu;
-
- ! if (!is_k_select && auto_preview_mode) goto auto_preview;
-
- cura = article_id;
- ! if (!auto_select_closed || !(articles[firsta+cura]->flag & A_CLOSED)) {
- ! toggle();
- ! if (!is_k_select && auto_select_subject) goto select_subject;
- ! mark();
- ! cura++;
- ! goto same_prompt;
- ! }
- !
- ! if (auto_select_closed < 0) {
- ! article_id = cura;
- ! goto open_subject;
- ! }
-
- + mi = menu_info + articles[firsta+cura]->menu_line;
- + if (mi->mi_unread == 0)
- + repl_attr_subject(A_KILL, A_SELECT, 1);
- + else if (mi->mi_selected == mi->mi_unread)
- + repl_attr_subject(auto_select_closed == 2 ? A_KILL : A_SELECT, 0, 1);
- + else
- + repl_attr_subject(auto_select_closed == 2 ? A_KILL : 0, A_SELECT, 1);
- goto same_prompt;
-
- case K_SELECT_INVERT:
- ***************
- *** 1330,1336 ****
- no_raw(); /* for x-on/x-off */
- for (cura = 0; cura <= numa; cura++) {
- toggle();
- ! mark();
- }
- fl;
-
- --- 1788,1796 ----
- no_raw(); /* for x-on/x-off */
- for (cura = 0; cura <= numa; cura++) {
- toggle();
- ! }
- ! for (cura = 0; cura <= numa; cura++) {
- ! if (IS_VISIBLE(articles[firsta+cura])) mark();
- }
- fl;
-
- ***************
- *** 1340,1354 ****
- cura = temp;
- goto same_prompt;
-
- -
- - case K_SELECT:
- - if (numa < 0) goto nextmenu;
- -
- - toggle();
- - mark();
- - cura++;
- - goto same_prompt;
- -
- case K_UNSELECT_ALL:
- if (last_k_cmd == K_UNSELECT_ALL)
- repl_attr_all(A_SELECT, 0, 1);
- --- 1800,1805 ----
- ***************
- *** 1368,1398 ****
- if (numa < 0) goto nextmenu;
-
- if (--cura < 0) cura = numa;
- goto same_prompt;
-
- case K_SELECT_SUBJECT:
- if (numa < 0) goto nextmenu;
-
- ! if (last_k_cmd != K_ARTICLE_ID && last_k_cmd != K_SELECT)
- toggle();
-
- select_subject:
- ! while (firsta+cura > 0 &&
- ! (articles[firsta+cura]->flag & (A_SAME | A_ALMOST_SAME)))
- ! cura--;
- !
- ! do {
- ! new_mark(last_attr);
- ! cura++;
- ! if (firsta+cura >= n_articles) break;
- ! } while (articles[firsta+cura]->flag & (A_SAME | A_ALMOST_SAME));
- !
- goto same_prompt;
-
- case K_SELECT_RANGE:
- if (numa < 0) goto nextmenu;
-
- ! if (last_k_cmd == K_ARTICLE_ID || last_k_cmd == K_SELECT) {
- cura--;
- if (cura < 0) cura = numa;
- } else
- --- 1819,1841 ----
- if (numa < 0) goto nextmenu;
-
- if (--cura < 0) cura = numa;
- + set_root_if_closed();
- goto same_prompt;
-
- case K_SELECT_SUBJECT:
- if (numa < 0) goto nextmenu;
-
- ! if (last_k_cmd != K_ARTICLE_ID)
- toggle();
-
- select_subject:
- ! repl_attr_subject(A_KILL, last_attr, 1);
- goto same_prompt;
-
- case K_SELECT_RANGE:
- if (numa < 0) goto nextmenu;
-
- ! if (last_k_cmd == K_ARTICLE_ID) {
- cura--;
- if (cura < 0) cura = numa;
- } else
- ***************
- *** 1410,1431 ****
-
- if (k_cmd != K_ARTICLE_ID) goto Prompt;
-
- ! if (last_k_cmd != K_ARTICLE_ID && last_k_cmd != K_SELECT)
- ! new_mark(last_attr);
- !
- ! if (article_id <= cura) {
- ! while (cura >= article_id) {
- ! new_mark(last_attr);
- ! cura--;
- ! }
- ! if (cura < 0) cura = 0;
- ! } else {
- ! while (cura <= article_id) {
- ! new_mark(last_attr);
- ! cura++;
- ! }
- ! if (cura > numa) cura = numa;
- }
- goto Prompt;
-
- case K_AUTO_SELECT:
- --- 1853,1865 ----
-
- if (k_cmd != K_ARTICLE_ID) goto Prompt;
-
- ! if (article_id > cura) {
- ! article_number tmp = cura;
- ! cura = article_id;
- ! article_id = tmp;
- }
- +
- + repl_attr(article_id, cura, A_KILL, last_attr, 1);
- goto Prompt;
-
- case K_AUTO_SELECT:
- ***************
- *** 1460,1467 ****
- case K_PREV_PAGE:
- if (firsta == 0 && nexta == n_articles) goto same_prompt;
-
- ! nexta = (firsta > 0 ? firsta : n_articles) - maxa;
- ! if (nexta <= 1) nexta = 0;
- goto nextmenu;
-
- case K_FIRST_PAGE:
- --- 1894,1917 ----
- case K_PREV_PAGE:
- if (firsta == 0 && nexta == n_articles) goto same_prompt;
-
- ! prevmenu:
- ! nexta = (firsta > 0 ? firsta : n_articles);
- !
- ! for (menu_length = maxa; menu_length > 0 && --nexta >= 0; ) {
- ! if (!IS_VISIBLE(articles[nexta])) continue;
- ! if (--menu_length > 0) {
- ! switch (menu_spacing) {
- ! case 0:
- ! break;
- ! case 1:
- ! if ((articles[nexta]->flag & A_ROOT_ART) == 0) break;
- ! case 2:
- ! --menu_length;
- ! break;
- ! }
- ! }
- ! }
- ! if (nexta < 0) nexta = 0;
- goto nextmenu;
-
- case K_FIRST_PAGE:
- ***************
- *** 1472,1481 ****
-
- case K_LAST_PAGE:
- if (nexta == n_articles) goto same_prompt;
- !
- ! nexta = n_articles - maxa;
- ! if (nexta <= 1) nexta = 0;
- ! goto nextmenu;
-
- case K_PREVIEW:
- if (numa < 0) goto nextmenu;
- --- 1922,1929 ----
-
- case K_LAST_PAGE:
- if (nexta == n_articles) goto same_prompt;
- ! firsta = 0;
- ! goto prevmenu;
-
- case K_PREVIEW:
- if (numa < 0) goto nextmenu;
- ***************
- *** 1616,1621 ****
- --- 2064,2070 ----
-
- menu_exit:
-
- + cur_bypass = o_bypass;
- n_selected = o_selected;
- firsta = o_firsta;
- in_menu_mode = o_mode;
- *** ./LAST/newsrc.c Thu Apr 11 22:05:41 1991
- --- newsrc.c Thu Apr 11 22:27:03 1991
- ***************
- *** 1010,1016 ****
-
- /*
- * Update .newsrc for one group.
- ! * sort_articles(0) MUST HAVE BEEN CALLED BEFORE USE.
- */
-
- export int rc_merged_groups_hack = 0;
- --- 1010,1016 ----
-
- /*
- * Update .newsrc for one group.
- ! * sort_articles(-2) MUST HAVE BEEN CALLED BEFORE USE.
- */
-
- export int rc_merged_groups_hack = 0;
- *** ./LAST/patchlevel.h Thu Apr 11 22:05:41 1991
- --- patchlevel.h Thu Apr 11 22:11:32 1991
- ***************
- *** 25,31 ****
- * 1990-11-07: Patch #12 (6.4.12) - LOW
- * 1991-02-06: Patch #13 (6.4.13) - MEDIUM
- * 1991-03-22: Patch #14 (6.4.14) - MEDIUM
- */
-
- ! #define PATCHLEVEL 14
-
- --- 25,32 ----
- * 1990-11-07: Patch #12 (6.4.12) - LOW
- * 1991-02-06: Patch #13 (6.4.13) - MEDIUM
- * 1991-03-22: Patch #14 (6.4.14) - MEDIUM
- + * 1991-04-02: Patch #15 (6.4.15) - LOW
- */
-
- ! #define PATCHLEVEL 15
-
- *** ./LAST/sort.c Fri Oct 5 19:07:19 1990
- --- sort.c Thu Apr 11 23:05:09 1991
- ***************
- *** 209,226 ****
- register long n;
- register flag_type same;
- fct_type cmp;
-
- for (n = n_articles; --n >= 0;)
- ! articles[n]->flag &= ~(A_SAME|A_ALMOST_SAME|A_NEXT_SAME);
-
- ! if (n_articles <= 1) return;
-
- if (mode == -1) mode = sort_mode;
-
- switch (mode) {
- default:
- case 0: /* arrival (no sort) */
- cmp = order_arrival;
- break;
- case 1: /* date-subject-date */
- case 2: /* subject-date */
- --- 209,236 ----
- register long n;
- register flag_type same;
- fct_type cmp;
- + extern int bypass_consolidation;
-
- + if (n_articles <= 0) return;
- +
- for (n = n_articles; --n >= 0;)
- ! articles[n]->flag &= ~(A_SAME|A_ALMOST_SAME|A_NEXT_SAME|A_ROOT_ART);
-
- ! if (n_articles == 1) {
- ! articles[0]->flag |= A_ROOT_ART;
- ! return;
- ! }
-
- if (mode == -1) mode = sort_mode;
-
- switch (mode) {
- + case -2: /* restore original ordering for update */
- + cmp = order_arrival;
- + break;
- default:
- case 0: /* arrival (no sort) */
- cmp = order_arrival;
- + bypass_consolidation = 1;
- break;
- case 1: /* date-subject-date */
- case 2: /* subject-date */
- ***************
- *** 228,236 ****
- --- 238,248 ----
- break;
- case 3: /* date only */
- cmp = order_date;
- + bypass_consolidation = 1;
- break;
- case 4: /* sender-date */
- cmp = order_from_date;
- + bypass_consolidation = 1;
- break;
- }
-
- ***************
- *** 237,242 ****
- --- 249,255 ----
- quicksort(articles, n_articles, article_header *, cmp);
-
- articles[0]->root_t_stamp = articles[0]->t_stamp;
- + articles[0]->flag |= A_ROOT_ART;
- for (n = n_articles - 1, app = articles + 1; --n >= 0; app++) {
- if (same = article_equal(app, app - 1)) {
- app[0]->root_t_stamp = app[-1]->root_t_stamp;
- ***************
- *** 244,249 ****
- --- 257,263 ----
- app[-1]->flag |= A_NEXT_SAME;
- } else {
- app[0]->root_t_stamp = app[0]->t_stamp;
- + app[0]->flag |= A_ROOT_ART;
- }
- }
-
- ***************
- *** 304,315 ****
- if (changed && n_articles > 0) {
- srca = articles;
- srca[0]->flag &= ~(A_SAME|A_ALMOST_SAME|A_NEXT_SAME);
- for (n = n_articles - 1, srca++; --n >= 0; srca++) {
- ! srca[0]->flag &= ~(A_SAME|A_ALMOST_SAME|A_NEXT_SAME);
- if (same = article_equal(srca, srca - 1)) {
- srca[0]->flag |= same;
- srca[-1]->flag |= A_NEXT_SAME;
- ! }
- }
- }
-
- --- 318,331 ----
- if (changed && n_articles > 0) {
- srca = articles;
- srca[0]->flag &= ~(A_SAME|A_ALMOST_SAME|A_NEXT_SAME);
- + srca[0]->flag |= A_ROOT_ART;
- for (n = n_articles - 1, srca++; --n >= 0; srca++) {
- ! srca[0]->flag &= ~(A_SAME|A_ALMOST_SAME|A_NEXT_SAME|A_ROOT_ART);
- if (same = article_equal(srca, srca - 1)) {
- srca[0]->flag |= same;
- srca[-1]->flag |= A_NEXT_SAME;
- ! } else
- ! srca[0]->flag |= A_ROOT_ART;
- }
- }
-
- *** ./LAST/variable.c Wed Feb 6 19:14:23 1991
- --- variable.c Thu Apr 11 22:11:33 1991
- ***************
- *** 32,37 ****
- --- 32,38 ----
- * Automatically expanded. ("unset" set var to NULL).
- * STR 3 Ordinary string, but cannot be "unset".
- * STR 4 (Expanded) file name - cannot be unset.
- + * STR 5 Ordinary string ("unset" set var to "").
- *
- * CODES n String initialized by list of key names.
- * A maximum of 16 CODES variables (n = 0 - 15) exist.
- ***************
- *** 63,68 ****
- --- 64,71 ----
- *backup_folder_path,
- *bak_suffix,
- *bug_address,
- + *counter_delim_left,
- + *counter_delim_right,
- *decode_header_file,
- *default_distribution,
- *default_save_file,
- ***************
- *** 119,124 ****
- --- 122,128 ----
- conf_dont_sleep,
- conf_group_entry,
- conf_junk_seen,
- + consolidated_menu,
- delay_redraw,
- dflt_kill_select,
- do_kill_handling,
- ***************
- *** 186,191 ****
- --- 190,196 ----
- also_read_articles,
- article_limit,
- auto_read_limit,
- + auto_select_closed,
- check_db_update,
- conf_entry_limit,
- collapse_subject,
- ***************
- *** 204,209 ****
- --- 209,215 ----
- mark_next_group,
- mark_read_return,
- mark_read_skip,
- + menu_spacing,
- message_history,
- min_pv_window,
- multi_key_guard_time,
- ***************
- *** 218,223 ****
- --- 224,230 ----
- re_layout_more,
- response_check_pause,
- retry_on_error,
- + save_closed_mode,
- save_counter_offset,
- scroll_last_lines,
- show_purpose_mode,
- ***************
- *** 291,296 ****
- --- 298,304 ----
- "auto-junk-seen", BOOL 0, (char **)&auto_junk_seen,
- "auto-preview-mode", BOOL 0, (char **)&auto_preview_mode,
- "auto-read-mode-limit", INT 0, (char **)&auto_read_limit,
- + "auto-select-closed", INT 0, (char **)&auto_select_closed,
- "auto-select-subject", BOOL 0, (char **)&auto_select_subject,
- "backup", BOOL 0, (char **)&keep_rc_backup,
- "backup-folder-path", STR 4, (char **)&backup_folder_path,
- ***************
- *** 311,316 ****
- --- 319,327 ----
- "confirm-entry-limit", INT 0, (char **)&conf_entry_limit,
- "confirm-junk-seen", BOOL 0, (char **)&conf_junk_seen,
- "confirm-messages", BOOL 0, (char **)&conf_dont_sleep,
- + "consolidated-menu", BOOL 1, (char **)&consolidated_menu,
- + "counter-delim-left", STR 5, (char **)&counter_delim_left,
- + "counter-delim-right", STR 5, (char **)&counter_delim_right,
- "cross-filter-seq", BOOL 0, (char **)&seq_cross_filtering,
- "cross-post", BOOL 0, (char **)&also_cross_postings,
- "data-bits", INT 0, (char **)&data_bits,
- ***************
- *** 375,380 ****
- --- 386,392 ----
- "marked-by-next-group", INT 0, (char **)&mark_next_group,
- "marked-by-read-return", INT 0, (char **)&mark_read_return,
- "marked-by-read-skip", INT 0, (char **)&mark_read_skip,
- + "menu-spacing", INT 1, (char **)&menu_spacing,
- "message-history", INT 0, (char **)&message_history,
- "min-window", INT 1, (char **)&min_pv_window,
- "mmdf-format", BOOL 0, (char **)&use_mmdf_folders,
- ***************
- *** 419,424 ****
- --- 431,437 ----
- "response-default-answer", STR 0, (char **)&response_dflt_answer,
- "retain-seen-status", BOOL 0, (char **)&retain_seen_status,
- "retry-on-error", INT 0, (char **)&retry_on_error,
- + "save-closed-mode", INT 0, (char **)&save_closed_mode,
- "save-counter", STR 3, (char **)&save_counter_format,
- "save-counter-offset", INT 0, (char **)&save_counter_offset,
- "save-header-lines", STR 0, (char **)&save_header_lines,
- ***************
- *** 622,627 ****
- --- 635,644 ----
- }
- STR_VAR = copy_str(val_string);
- break;
- + case 5:
- + STR_VAR = (on && val_string) ? copy_str(val_string) : "";
- + break;
- +
- }
- break;
-
-